package com.katze.boot.applet.ssh.controller;

import com.katze.boot.applet.ssh.CommandType;
import com.katze.boot.applet.ssh.SSHExecutor;
import com.katze.boot.applet.ssh.entity.SecureSSHProcessEntity;
import com.katze.boot.applet.ssh.entity.SecureSSHSessionEntity;
import com.katze.boot.applet.ssh.service.SecureSSHProcessService;
import com.katze.boot.applet.ssh.service.SecureSSHSessionService;
import com.katze.boot.plugins.shiro.annotations.RestControllerMapping;
import com.katze.boot.plugins.shiro.annotations.RestRequestMapping;
import com.katze.common.Message;
import com.katze.common.controller.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.*;
import java.util.stream.Collectors;

@RestControllerMapping({"/ssh"})
public class SecureSSHController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(SecureSSHController.class);

    @Autowired
    private SecureSSHSessionService sshSessionService;

    @Autowired
    private SecureSSHProcessService sshProcessService;

    @RestRequestMapping(value = "/session", method = RequestMethod.GET, permits = "secure:ssh:view")
    public Message sessionList(String owner) {
        List<SecureSSHSessionEntity> rs = sshSessionService.findByOwner(owner);
        return Message.ok().data(rs);
    }

    @RestRequestMapping(value = "/session", method = {RequestMethod.POST, RequestMethod.PUT})
    public Message edit(SecureSSHSessionEntity entity){
        if (entity.getId() == null) {
            entity.setCreateTime(new Date());
            this.sshSessionService.save(entity);
            return Message.ok("主机信息添加成功");
        } else {
            boolean rs = this.sshSessionService.updateById(entity);
            return rs? Message.ok("主机信息修改成功"):Message.error("主机信息可能不存在");
        }
    }

    @RestRequestMapping(value = "/session", method = RequestMethod.DELETE)
    public Message deleteSession(String id){
        sshSessionService.removeById(id);
        return Message.ok("删除成功");
    }

    @RestRequestMapping(value = "/process", method = RequestMethod.GET, permits = "secure:ssh:view:precess")
    public Message processList(String sessionId) {
        List<SecureSSHProcessEntity> rs = sshProcessService.findProcessBySession(sessionId);
        return toDataTable(rs);
    }

    @RestRequestMapping(value = "/process", method = {RequestMethod.POST, RequestMethod.PUT})
    public Message edit(SecureSSHProcessEntity entity){
        if (entity.getId() == null) {
            entity.setCreateTime(new Date());
            this.sshProcessService.saveOrUpdate(entity);
            return Message.ok("进程信息创建成功");
        } else {
            this.sshProcessService.saveOrUpdate(entity);
            return Message.ok("进程信息修改成功");
        }
    }

    @RestRequestMapping(value = "/process", method = RequestMethod.DELETE)
    public Message deleteProcess(String id){
        sshProcessService.removeById(id);
        return Message.ok("删除成功");
    }

    @RestRequestMapping(value = "/execute", method = RequestMethod.POST)
    public Message execute(String type, String[] ids){
        List<SecureSSHProcessEntity> entities = sshProcessService.listByIds(Arrays.asList(ids));
        Map<String, List<SecureSSHProcessEntity>> map = entities.stream().collect(Collectors.groupingBy(SecureSSHProcessEntity::getSessionId));
        List<Map<String, String>> rs = new ArrayList<>();
        for (String sessionId : map.keySet()) {
            SecureSSHSessionEntity session = sshSessionService.getById(sessionId);
            if (session != null) {
                try (SSHExecutor executor = SSHExecutor.builder().connection(session.getHost(), session.getPort(), session.getUsername(), session.getPassword()).build()){
                    List<SecureSSHProcessEntity> processes = map.get(sessionId);
                    for (SecureSSHProcessEntity process : processes) {
                        Map<String, String> msg = new HashMap<>();
                        msg.put("title", process.getName());
                        msg.put("description", CommandType.STATUS.name().equals(type.toUpperCase())?"进程不存在":"     ");
                        try {
                            executor.execute(CommandType.valueOf(type.toUpperCase()).command(process),
                                    (out, err) -> msg.merge("description", out.toString(), (v1, v2) -> StringUtils.isBlank(v2)? v1:v2));
                        } catch (Exception e) {
                            log.error("{}", process, e);
                            msg.put("type", "error");
                            msg.put("description", e.getMessage());
                        } finally {
                            rs.add(msg);
                        }
                    }
                } catch (Exception e) {
                    log.error("{} 连接失败", session, e);
                    return Message.error(session + "连接失败");
                }
            }
        }
        return Message.ok().data(rs);
    }

    @RestRequestMapping(value = "/test", method = RequestMethod.GET)
    public Message test(String sessionId){
        SecureSSHSessionEntity session = sshSessionService.getById(sessionId);
        if (session != null) {
            try {
                SSHExecutor.builder().connection(session.getHost(), session.getPort(), session.getUsername(), session.getPassword()).test();
                return Message.ok("连接成功");
            } catch (Exception e) {
                return Message.error("连接失败");
            }
        }
        return Message.ok();
    }

}
